<!--  -->
<template>
  <div :style="{width:containerWidth}">
    <textarea :id="tinymceId" />
  </div>
</template>

<script>
import config from '@/config'
import { plugins, toolbar } from './config'
import load from './dynamicLoadScript'
import { MessageBox } from 'element-ui'
import { nextTick, ref, onDeactivated, watchEffect, computed } from '@vue/composition-api';
import mixin from '@/utils/mixin'
const { $http, get } = mixin()

// dynamic load tinymce from cdn
function init(props, emit) {
  const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'

  const hasChange = ref(false)
  const hasInit = ref(false)
  const tinymceId = ref(props.id)
  const fullscreen = ref(false)

  load(tinymceCDN, (err) => {
    if (err) {
      MessageBox.error(err.message)
      return
    }
    nextTick(() => {
      initTinymce()
    })
  })

  function initTinymce() {
    window.tinymce.init({
      selector: `#${tinymceId.value}`,
      statusbar: false,
      language: 'zh_CN',
      height: props.height,
      body_class: 'panel-body',
      object_resizing: false,
      toolbar: props.toolbar.length > 0 ? props.toolbar : toolbar,
      menubar: props.menubar,
      plugins: plugins,
      end_container_on_empty_block: true,
      powerpaste_word_import: 'clean',
      code_dialog_height: 450,
      code_dialog_width: 1000,
      advlist_bullet_styles: 'square',
      advlist_number_styles: 'default',
      imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
      default_link_target: '_blank',
      link_title: false,
      nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
      init_instance_callback: editor => {
        if (props.value) {
          editor.setContent(props.value)
        }
        hasInit.value = true
        editor.on('NodeChange Change KeyUp SetContent', () => {
          hasChange.value = true
          emit('input', editor.getContent())
        })
      },
      setup(editor) {
        editor.on('FullscreenStateChanged', (e) => {
          fullscreen.value = e.state
        })
      },
      convert_urls: false,

      async images_upload_handler(blobInfo, success, failure, progress) {
        progress(0);

        const formData = new FormData();
        formData.append('DT_TOKEN', get.token);
        // formData.append('key', response.data.qiniu_key);
        formData.append('file', blobInfo.blob());
        let { url } = await $http.post(config.url + "/sys/oss/upload", formData)

        success(url);
        progress(100);
      },
    })
  }

  const containerWidth = computed(() => {
    const width = props.width
    if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
      return `${width}px`
    }
    return width
  })

  let stop = watchEffect(() => {
    if (!hasChange.value && hasInit.value) {
      nextTick(() =>
        window.tinymce.get(tinymceId.value).setContent(props.value || ''))
    }
  })
  function destroyTinymce() {
    const tinymce = window.tinymce.get(tinymceId.value)
    if (fullscreen.value) {
      tinymce.execCommand('mceFullScreen')
    }

    if (tinymce) {
      tinymce.destroy()
      stop()
    }
  }

  // 卸载组件时销毁
  onDeactivated(destroyTinymce)

  return {
    tinymceId,
    containerWidth
  }
}

export default {
  name: '',
  props: {
    id: {
      type: String,
      default: function () {
        return 'vue-tinymce-' + + new Date() + ((Math.random() * 1000).toFixed(0) + '')
      }
    },
    value: {
      type: String,
      default: ''
    },
    toolbar: {
      type: Array,
      required: false,
      default() {
        return []
      }
    },
    menubar: {
      type: String,
      default: 'file edit insert view format table'
    },
    height: {
      type: [Number, String],
      required: false,
      default: 360
    },
    width: {
      type: [Number, String],
      required: false,
      default: 'auto'
    }
  },
  setup(props, { emit }) {
    return {
      ...init(props, emit)
    }
  }
}

</script>

<style scoped>
</style>